package com.example.demo1;

import android.content.Context;
import android.util.AttributeSet;
import android.view.Gravity;
import android.widget.LinearLayout;
import android.widget.Scroller;

public class KAnimationLayout extends LinearLayout implements Runnable
{
	private static final int ANIM_DURATION = 500;
	private int mDuration = ANIM_DURATION;
	private Scroller mScroller;

	private int	mTotalHeight = -1;
	private int mOldHeight = -1;
	
	private boolean isFromDownToUp = false;
	
	public void setFromDownToUp(boolean isFromDownToUp)
	{
		this.isFromDownToUp = isFromDownToUp;
	}

	public KAnimationLayout(Context context, AttributeSet attrs)
	{
		super(context, attrs);
		setGravity(Gravity.BOTTOM);
	}

	public KAnimationLayout(Context context)
	{
		this(context, null);
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		if(mTotalHeight >= 0)
		{
			int height = measureHeight(heightMeasureSpec);
			setMeasuredDimension(getMeasuredWidth(), height);
		}
	}
	
	private int measureHeight(int measureSpec) {
		int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
        	result = mTotalHeight;
        	if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        return result;
	}
	
	public void expandAnimation(Runnable endAnimListener)
	{
		onAnimaitionEndListener = endAnimListener;
		int height;
		if (mOldHeight <= 0)
		{
			mTotalHeight = -1;
			measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
			mOldHeight = height = getMeasuredHeight();
		}
		else
		{
			height = mOldHeight;
		}
		
		mTotalHeight = 0;
		if (mScroller == null)
			mScroller = new Scroller(getContext());
		mScroller.abortAnimation();
		
		if (isFromDownToUp)
		{
			mScroller.startScroll(0, 0, 0, -height, mDuration);
		}
		else
		{
			mScroller.startScroll(0, 0, 0, height, mDuration);
		}
		
		post(this);
	}
	
	public void shrinkAnimation(Runnable endAnimListener)
	{
		onAnimaitionEndListener = endAnimListener;
		if (mScroller == null)
			mScroller = new Scroller(getContext());
		mScroller.abortAnimation();
		
		if (isFromDownToUp)
		{
			mScroller.startScroll(0, 0, 0, getHeight(), mDuration);
		}
		else
		{
			mScroller.startScroll(0, getHeight(), 0, -getHeight(), mDuration);
		}
		
		post(this);
	}
	
	/**
	 * View高度发生变化时，要主动调用。因为保存了之前View的高度。
	 */
	public void resetHeight()
	{
		mTotalHeight = -1;
		mOldHeight = -1;
		requestLayout();
	}
	
	public void setAnimDuration(int duration)
	{
		this.mDuration = duration;
	}
	
	public boolean isFinished()
	{
		if (mScroller != null)
		{
			return mScroller.isFinished();
		}
		return true;
	}

	@Override
	public void run()
	{
		if (!mScroller.computeScrollOffset())
		{
			mScroller.abortAnimation();
			if (onAnimaitionEndListener != null)
				onAnimaitionEndListener.run();
			return;
		}
		
		int currY = mScroller.getCurrY();
		
//		System.out.println("currY = " + currY);
		
		mTotalHeight = currY;
		
		requestLayout();
		invalidate();
		
		post(this);
	}
	
	public Runnable onAnimaitionEndListener;

	public boolean isExpanded()
	{
		return getVisibility() == VISIBLE && (mTotalHeight > 0 || getHeight() > 0);
	}
}
